package cn.gcjxsc.messaging.sink;

import cn.gcjxsc.common.consts.RedPackType;
import cn.gcjxsc.common.data.notify.redpack.RedPackData;
import cn.gcjxsc.common.util.validator.BindResult;
import cn.gcjxsc.data.redpack.MerRedPackData;
import cn.gcjxsc.data.redpack.RedPackRate;
import cn.gcjxsc.entity.mall.BaseOrder;
import cn.gcjxsc.entity.mall.ShoppingOrderExt;
import cn.gcjxsc.entity.member.Member;
import cn.gcjxsc.entity.member.WxMember;
import cn.gcjxsc.entity.member.integral.RedPackFlag;
import cn.gcjxsc.entity.merchant.Merchant;
import cn.gcjxsc.entity.merchant.MerchantAccount;
import cn.gcjxsc.entity.merchant.Store;
import cn.gcjxsc.entity.merchant.redpack.RedPackRecord;
import cn.gcjxsc.messaging.source.WxRedPackSource;
import cn.gcjxsc.service.integral.MemberWxRedPackService;
import cn.gcjxsc.service.mall.OrderService;
import cn.gcjxsc.service.member.MemberService;
import cn.gcjxsc.service.merchant.MerchantService;
import cn.gcjxsc.service.merchant.StoreService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Map;
import java.util.Random;

/**
 * @author pumbaa
 * @since 1.0
 */
public abstract class CashSink {
    protected Logger logger = LoggerFactory.getLogger(CashSink.class);
    @Autowired
    protected OrderService orderService;
    @Autowired
    protected StoreService storeService;
    @Autowired
    protected MerchantService merchantService;
    @Autowired
    protected MemberService memberService;
    @Autowired
    protected MemberWxRedPackService redPackService;
    /**
     * 微信红包发送通知
     */
    @Autowired
    protected WxRedPackSource source;

    protected void processCash(String sn, Integer type, String remark) {
        RedPackRecord redPackRecord = redPackService.findBySnAndType(sn, type);
        if (null == redPackRecord) {
            BaseOrder order = orderService.findShoppingOrderBySn(sn);
            BindResult bindResult = new BindResult();
            boolean isValid = redPackService.checkOrder(order, bindResult);
            if (!isValid) {
                logger.error("无效订单.{}, {}", sn, bindResult.getErrorMsg());
                return;
            }
            Member member = memberService.findById(order.getOwnerId());
            WxMember wxMember = memberService.findWxMemberById(member.getWxMemberId());
            if (null == wxMember || StringUtils.isEmpty(wxMember.getOpenid())) {
                logger.error("该会员没有微信有效信息,无法发送红包.订单号:{}, 会员ID:{}", sn, member.getId());
                return;
            }

            ShoppingOrderExt ext = orderService.findExtByOrderId(order.getId());
            Integer storeId = ext.getStoreId();
            Store store = storeService.findById(storeId);
            Merchant merchant = merchantService.findById(store.getMerchantId());

            Map<String, String> storeSetting = redPackService.findStoreSetting(store);
            String rule = storeSetting.get("redPackRule");
            if (StringUtils.isEmpty(rule)) {
                rule = "2";
            }
            BigDecimal redPackRate;
            if (rule.equalsIgnoreCase("2")) {
                //固定比例
                String redPackRateStr = storeSetting.get("redPackRate");
                if (StringUtils.isEmpty(redPackRateStr)) {
                    logger.info("红包比例没有设置.无法计算收益.订单号:{}, 店铺id:{}", sn, store.getId());
                    return;
                }
                redPackRate = new BigDecimal(redPackRateStr);
                if (redPackRate.compareTo(BigDecimal.ZERO) < 1) {
                    logger.info("店铺没有开启红包收益.sn:{}, storeId:{}", sn, store.getId());
                    return;
                }
            } else {
                //随机比例
                String maxStr = storeSetting.get("redPackRateRandomMax");
                String minStr = storeSetting.get("redPackRateRandomMin");
                if (StringUtils.isEmpty(maxStr) && StringUtils.isEmpty(minStr)) {
                    logger.info("商户使用随机比例,但没有设置相应的值");
                    return;
                }
                BigDecimal max = new BigDecimal(maxStr);
                BigDecimal min = new BigDecimal(minStr);

                if (max.compareTo(BigDecimal.ZERO) <1) {
                    logger.info("店铺没有开启红包收益.sn:{}, storeId:{}", sn, store.getId());
                    return;
                }

                if (max.compareTo(min) < 1) {
                    redPackRate = max;
                } else {
                    Random random = new Random();

                    String s = max.subtract(min).toString();
                    int len = s.length() - s.indexOf(".") - 1;
                    double pow = Math.pow(10, len);
                    BigDecimal bigDecimalPow = BigDecimal.valueOf(pow);
                    BigDecimal maxInt = max.multiply(bigDecimalPow);
                    BigDecimal minInt = min.multiply(bigDecimalPow);

                    int ma = maxInt.intValue();
                    int mi = minInt.intValue();

                    int difInt = random.nextInt(ma) % random.nextInt(ma - mi + 1) + mi;
                    redPackRate = BigDecimal.valueOf(difInt).divide(bigDecimalPow, len, BigDecimal.ROUND_DOWN);
                }
            }

            RedPackRate rates = redPackService.getRedPackRates();
            BigDecimal amountRate;
            if (type == RedPackType.BUY.getType()) {
                amountRate = new BigDecimal(rates.getSendRate());
            } else {
                amountRate = new BigDecimal(rates.getShareRate());
            }
            //红包金额
            BigDecimal redPackSendAmount = ext.getGoodsAmount().multiply(redPackRate).multiply(amountRate);
            redPackSendAmount = redPackService.processAmount(redPackSendAmount);
            if (redPackSendAmount.compareTo(BigDecimal.ZERO) <= 0) {
                logger.info("红包金额为0.{}", sn);
                return;
            }
            MerchantAccount account = redPackService.findWxCashAccount(merchant);
            if (account.getAmount().compareTo(redPackSendAmount) < 0) {
                logger.info("商户 {} 红包余额不足. {}", merchant.getId(), sn);
                return;
            }

            MerRedPackData merRedPackData = new MerRedPackData();
            merRedPackData.setAmountRate(amountRate);
            merRedPackData.setBaseAmount(ext.getGoodsAmount());
            merRedPackData.setMemberId(order.getOwnerId());
            merRedPackData.setMerchantId(merchant.getId());
            merRedPackData.setStoreId(store.getId());
            merRedPackData.setStoreName(store.getName());
            merRedPackData.setRate(redPackRate);
            merRedPackData.setRedPackAmount(redPackSendAmount);
            merRedPackData.setSn(order.getSn());
            merRedPackData.setType(type);
            merRedPackData.setRemark(remark);

            redPackRecord = redPackService.newRedPackRecord(merRedPackData);
            redPackRecord.setOpenid(wxMember.getOpenid());
            try {
                redPackService.processSendRedPack(account, redPackRecord);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("数据处理出错.订单号:{}, {}", sn, e.getMessage());
                return;
            }
        }

        if (redPackRecord.getStatus() == 1) {
            logger.error("当前记录已处理.{}", sn, type);
            return;
        }

        RedPackData data = new RedPackData();
        data.setAmount(Math.abs(redPackRecord.getAmount().multiply(BigDecimal.valueOf(100)).intValue()));
        data.setOpenid(redPackRecord.getOpenid());
        data.setRemark(redPackRecord.getRemark());
        data.setSn(redPackRecord.getSourceSn());
        data.setStoreId(redPackRecord.getStoreId());
        data.setStoreName(redPackRecord.getStoreName());
        data.setType(type);

        source.sendRedPackMessage(data);
        logger.info("发送微信红包通知.{}", sn);
    }
}
